﻿using AutoMapper;
using MyTodo.Api.Context.UnitOfWork;
using MyTodo.Api.Context;
using MyTodo.Shared.Dtos;
using MyTodo.Shared.Parameters;
using System.Collections.ObjectModel;

namespace MyTodo.Api.Service
{
    public class ToDoService : IToDoService
    {
        private readonly IUnitOfWork work;
        private readonly IMapper mapper;

        public ToDoService(IUnitOfWork work, IMapper mapper)
        {
            this.work = work;
            this.mapper = mapper;
        }
        public async Task<ApiResponse> AddAsync(ToDoDto entity)
        {
            try
            {
                var todo = mapper.Map<ToDo>(entity);
                await work.GetRepository<ToDo>().InsertAsync(todo);
                // 添加创建时间
                todo.CreateDate = DateTime.Now;
                todo.UpdateDate = DateTime.Now;
                if (await work.SaveChangesAsync() > 0)
                    return new ApiResponse(true, todo);
                return new ApiResponse("添加数据失败");
            }
            catch (Exception ex)
            {
                return new ApiResponse(ex.Message);
            }

        }

        public async Task<ApiResponse> DeleteAsync(int id)
        {
            try
            {
                var repository = work.GetRepository<ToDo>();
                var todo = repository.GetFirstOrDefault(predicate: x => x.Id.Equals(id));

                repository.Delete(todo);

                if (await work.SaveChangesAsync() > 0)
                    return new ApiResponse(true, "");
                return new ApiResponse("删除数据失败");
            }
            catch (Exception ex)
            {
                return new ApiResponse(ex.Message);
            }
        }

        public async Task<ApiResponse> GetAllAsync(QueryParameter query)
        {
            try
            {
                var repository = work.GetRepository<ToDo>();
                var todos = await repository.GetPagedListAsync(predicate: x => string.IsNullOrWhiteSpace(query.Search) || x.Title.Contains(query.Search),
                    pageIndex: query.PageIndex,
                    pageSize: query.PageSize,
                    orderBy: source => source.OrderByDescending(t => t.CreateDate));
                return new ApiResponse(true, todos);
            }
            catch (Exception ex)
            {
                return new ApiResponse(ex.Message);
            }
        }

        public async Task<ApiResponse> GetAllAsync(ToDoParameter query)
        {
            try
            {
                var repository = work.GetRepository<ToDo>();
                var todos = await repository.GetPagedListAsync(predicate: x => (string.IsNullOrWhiteSpace(query.Search) || x.Title.Contains(query.Search))
                && (query.Status == null || x.Status.Equals(query.Status)),
                    pageIndex: query.PageIndex,
                    pageSize: query.PageSize,
                    orderBy: source => source.OrderByDescending(t => t.CreateDate));
                return new ApiResponse(true, todos);
            }
            catch (Exception ex)
            {
                return new ApiResponse(ex.Message);
            }
        }

        public async Task<ApiResponse> GetSingleAsync(int id)
        {
            try
            {
                var repository = work.GetRepository<ToDo>();
                var todo = await repository.GetFirstOrDefaultAsync(predicate: x => x.Id.Equals(id));
                return new ApiResponse(true, todo);
            }
            catch (Exception ex)
            {
                return new ApiResponse(ex.Message);
            }
        }

        public async Task<ApiResponse> Summary()
        {
            try
            {
                var todos = await work.GetRepository<ToDo>().GetAllAsync(
                    orderBy: s => s.OrderByDescending(t => t.CreateDate));
                var memos = await work.GetRepository<Memo>().GetAllAsync(
                    orderBy: s => s.OrderByDescending(t => t.CreateDate));

                SummaryDto summary = new SummaryDto();
                // 汇总待办事项
                summary.Sum = todos.Count();
                // 统计完成数量
                summary.CompletedCount = todos.Where(x => x.Status == 1).Count();
                // 统计完成率
                summary.CompletedRatio = (summary.CompletedCount / (double)summary.Sum).ToString("0%");
                // 汇总备忘录数量
                summary.MemoCount = memos.Count();
                summary.TodoList = new ObservableCollection<ToDoDto>(mapper.Map<List<ToDoDto>>(todos.Where(t => t.Status == 0)));
                summary.MemoList = new ObservableCollection<MemoDto>(mapper.Map<List<MemoDto>>(memos));

                return new ApiResponse(true, summary);
            }
            catch (Exception ex)
            {
                return new ApiResponse(false, "");
            }
        }

        public async Task<ApiResponse> UpdateAsync(ToDoDto entity)
        {
            try
            {

                var repository = work.GetRepository<ToDo>();
                var todo = await repository.GetFirstOrDefaultAsync(predicate: x => x.Id.Equals(entity.Id));
                var createDate = todo.CreateDate;

                todo = mapper.Map<ToDo>(entity);
                todo.UpdateDate = DateTime.Now;
                todo.CreateDate = createDate;
                repository.Update(todo);

                if (await work.SaveChangesAsync() > 0)
                    return new ApiResponse(true, todo);
                return new ApiResponse(false, "更新数据异常");
            }
            catch (Exception ex)
            {
                return new ApiResponse(ex.Message);
            }
        }
    }
}
